package org.september.pisces.user.permission.service;

import java.util.ArrayList;
import java.util.List;

import org.september.core.component.ApplicationContextHolder;
import org.september.core.exception.BusinessException;
import org.september.core.util.MD5;
import org.september.core.util.PasswordUtil;
import org.september.pisces.cache.aop.SimpleCache;
import org.september.pisces.user.permission.entity.RolePermission;
import org.september.pisces.user.permission.entity.SystemRole;
import org.september.pisces.user.permission.entity.SystemUser;
import org.september.pisces.user.permission.utils.EncryptUtil;
import org.september.pisces.user.permission.utils.UserSessionHelper;
import org.september.pisces.user.permission.vo.PermissionTreeNode;
import org.september.simpleweb.utils.IpUtils;
import org.september.simpleweb.utils.SessionHelper;
import org.september.smartdao.CommonDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import jakarta.servlet.http.HttpServletRequest;

@Service
public class SystemUserService {
	
	@Autowired
	private CommonDao dao;
	
	@Autowired
	private OperationLogService operationLogService;
	
	@Autowired
	private UserPwdErrorCheckService userPwdErrorCheckService;
	
	public SystemUser login(String username , String password,boolean byToken) {
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
		String ip = IpUtils.getIpAddr(request);
		SystemUser user =getUserByUserName(username);
		if(user==null) {
			userPwdErrorCheckService.checkPwdErrorLimits(ip);
			throw new BusinessException("用户不存在");
		}
		try {
			/*if (password.endsWith("==")){
				//先解密
	            password  = EncryptUtil.decrypt(password);
	        }*/
			password  = EncryptUtil.decrypt(password);
		} catch (Exception e) {
			throw new BusinessException("密码验证错误",e);
		}
		password = MD5.md5WithDefaultSalt(password);
		if(!password.equals(user.getPassword())) {
			userPwdErrorCheckService.checkPwdErrorLimits(ip);
//			throw new BusinessException("用户名或密码错误");
		}
		if(byToken) {
			String token = TokenSessionManager.addSessionUser(user);
			user.setToken(token);
		}else {
			UserSessionHelper.setLoginUser(user);
		}
		userPwdErrorCheckService.pass(ip);
		if("superadmin".equals(user.getUsername())) {
			PiscesPermissionService piscesPermissionService = ApplicationContextHolder.getContext().getBean(PiscesPermissionService.class);
			for(PermissionTreeNode node : piscesPermissionService.getAllPermissions()) {
				user.getPermitUrlList().addAll(node.getResource());
			}
		}else {
			List<RolePermission> perms = getPermissionOfUser(user.getId());
			for(RolePermission rp : perms) {
				user.getPermitUrlList().add(rp.getResource());
			}
		}
		UserOnlineStatusService.setCurrentUserSid(user.getId(), SessionHelper.getSession().getId());
		return user;
	}
	
	
	public void doResetMyPwd(Long id, String oldPwd, String newPwd, String newPwdRepeat) throws Exception {
		if (StringUtils.isEmpty(oldPwd)) {
			throw new BusinessException("旧密码不能为空");
		}
		if (StringUtils.isEmpty(newPwd)) {
			throw new BusinessException("新密码不能为空");
		}
		if (StringUtils.isEmpty(newPwdRepeat)) {
			throw new BusinessException("确认密码不能为空");
		}
		
		oldPwd = EncryptUtil.decrypt(oldPwd);
        newPwd = EncryptUtil.decrypt(newPwd);
        newPwdRepeat = EncryptUtil.decrypt(newPwdRepeat);
        
		if (!PasswordUtil.isComplexPwd(newPwd)) {
			throw new BusinessException("密码不能少于8位，且包含数字，大写字母，小写字母，特殊字符中任意两种组合");
		}
		if (!StringUtils.pathEquals(newPwd, newPwdRepeat)) {
			throw new BusinessException("两次输入的密码不一样");
		}
		if (StringUtils.pathEquals(oldPwd, newPwd)) {
			throw new BusinessException("新密码不能和旧密码一致");
		}

		SystemUser po = dao.get(SystemUser.class, id);
		if (!StringUtils.pathEquals(MD5.md5WithDefaultSalt(oldPwd), po.getPassword())) {
			throw new BusinessException("旧密码错误");
		}
		po.setPassword(MD5.md5WithDefaultSalt(newPwd));
		dao.update(po);
		operationLogService.addLog("修改了用户【"+po.getUsername()+"】的密码");
	}
	
//	public boolean hasPermission(long userId,String resource) {
//		List<RolePermission> perms = getPermissionOfUser(userId);
//		for(RolePermission perm: perms) {
//			if(perm.getResource().equals(resource)) {
//				return true;
//			}
//		}
//		return false;
//	}
	
	public List<SystemRole> getRolesOfUser(long userId){
		SystemUser su = dao.get(SystemUser.class, userId);
		List<Long> idList = new ArrayList<>();
		if(StringUtils.hasText(su.getRoleIds())){
			for(String idStr : su.getRoleIds().split(";")) {
				if(StringUtils.hasText(idStr)) {
					idList.add(Long.valueOf(idStr));
				}
			}
		}
		if(idList.isEmpty()) {
			return null;
		}
		return dao.listByIds(SystemRole.class, idList);
	}
	
	//TODO缓存
	public List<RolePermission> getPermissionOfUser(long userId){
		List<RolePermission> perms = new ArrayList<>();
		List<SystemRole> roles = getRolesOfUser(userId);
		if(roles==null || roles.isEmpty()) {
			return perms;
		}
		for(SystemRole role : roles) {
			RolePermission rpVo = new RolePermission();
			rpVo.setRoleId(role.getId());
			perms.addAll(dao.listByExample(rpVo));
		}
		return perms;
	}
	
	public List<RolePermission> getPermissionOfRole(long roleId){
		RolePermission vo= new RolePermission();
		vo.setRoleId(roleId);
		return dao.listByExample(vo);
	}
	
	public SystemUser getUserByUserName(String username) {
		SystemUser vo = new SystemUser();
		vo.setUsername(username);
		vo.setDeleteFlag(0);
		SystemUser po = dao.getByExample(vo);
		return po;
	}
	
	@SimpleCache
	public SystemUser getUserById(Long id) {
		SystemUser po = dao.get(SystemUser.class, id);
		return po;
	}
	
	public void addUser(SystemUser su) {
		SystemUser po = getUserByUserName(su.getUsername());
		if(po!=null) {
			throw new BusinessException("用户名 "+su.getUsername()+" 已存在!");
		}
		if (!PasswordUtil.isComplexPwd(su.getPassword())) {
			throw new BusinessException("密码长度至少8位，且包含数字，大写字母，小写字母，特殊字符中任意两种组合!");
		}
		
		String md5Password = MD5.md5WithDefaultSalt(su.getPassword());
		su.setPassword(md5Password);
		if(!su.getRoleIds().endsWith(";")) {
			su.setRoleIds(su.getRoleIds()+";");
		}
		dao.save(su);
	}
}
